import http.client
from xml.dom.minidom import parse, parseString, Node

devKey = '7142058e-85d2-461a-8831-380c1682f246'
appKey = 'QianZhou-Boat-PRD-78e35c535-9fd7d7ab'
certKey = 'PRD-8e35c535640e-e0a1-4c10-832b-8f84'
serverUrl = 'api.ebay.com'
userToken = 'AgAAAA**AQAAAA**aAAAAA**A75qWQ**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6AClIWkD5mEogmdj6x9nY+seQ**T9IDAA**AAMAAA**hz1eryOEZ5Ip43zd8PKcBVFX4OLzEkkA4GTXIcCKzw8fyKGfMOwAAlOzLKFvqLn7gXxS8wj+n3VQ6Pl1/x/6m2wU8qw6gzxU8pNitPF+GQQAtO2Jn1asDy3vHLIojQHihiJ149POlIjsDGJnjrAi/ULuOyvnmTqAuMcxq7k5DZbibWLxEQgiAyxzZxE0XxV3hy9dXKz6CT+Hjt/7GNcv6kEY5BE5L/gvJ6EJtn0JfgyCwUwu9MnO3CGpo+N5n7ptEWTVcjB0sj+DEQtygwzKibOr+e+uAOvIkMX5YUhKGpzkUU1Xjc6D9h2OCXunJ7SqC57gn+3YsKm6Wx5gNiII9r66sB1LXEAG9NBbhwPHolQMLAsMAiKaif+NNWjpbrl24pHZXsBPPImXsYErfMBOPFYdhGLSSr2dejKV1tq9VSoUuZURxJkRYxNwovF5uEmJyf3+NpjUFTPsgFu9aWYUqebi3lGU4UWAww2vb+KhDpA3QUSGHSGMwaJhopWzb6wJMVyfO2OfH4J1bBGH8J8i983GzmtfN1tUhXzQrJMk0Q8lC4aqxH95ncLZcyAvyqkpog5kxPv1Q2ZdAVZ1TFuGJ3PDLFLRNC4F4F4fg0YpzfDCVUOvujaG05TPEwKBJxj2WQWPgf46RoRQD199qj9tV4kynXsmjd+++MNQdHUfWJg4et5Ws19ZgSOB47VKA6nPYXCgGdbdzpudCoxevDeKG5BJFzcoCb/eqBFLY/i8w1qH6H7wgHcV4kWhVvOgCHmY'


def getHeaders(apicall, siteID="0", compatabilityLevel="433"):
    headers = {"X-EBAY-API-COMPATIBILITY-LEVEL": compatabilityLevel,
               "X-EBAY-API-DEV-NAME": devKey,
               "X-EBAY-API-APP-NAME": appKey,
               "X-EBAY-API-CERT-NAME": certKey,
               "X-EBAY-API-CALL-NAME": apicall,
               "X-EBAY-API-SITEID": siteID,
               "Content-Type": "text/xml"}
    return headers


def sendRequest(apicall, xmlparameters):
    connection = http.client.HTTPSConnection(serverUrl)
    connection.request("POST", '/ws/api.dll', xmlparameters, getHeaders(apicall))
    response = connection.getresponse()
    if response.status != 200:
        print("Error sending request:" + response.reason)
        return None
    else:
        data = response.read()
        connection.close()
    return data


def getSingleValue(node, tag):
    nl = node.getElementsByTagName(tag)
    if len(nl) > 0:
        tagNode = nl[0]
        if tagNode.hasChildNodes():
            return tagNode.firstChild.nodeValue
    return '-1'


def doSearch(query, categoryID=None, page=1):
    # build xml
    xml = "<?xml version='1.0' encoding='utf-8'?>" + \
          "<GetSearchResultsRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">" + \
          "<RequesterCredentials><eBayAuthToken>" + \
          userToken + \
          "</eBayAuthToken></RequesterCredentials>" + \
          "<Pagination>" + \
          "<EntriesPerPage>200</EntriesPerPage>" + \
          "<PageNumber>" + str(page) + "</PageNumber>" + \
          "</Pagination>" + \
          "<Query>" + query + "</Query>"
    if categoryID is not None:
        xml += "<CategoryID>" + str(categoryID) + "</CategoryID>"
    xml += "</GetSearchResultsRequest>"

    data = sendRequest('GetSearchResults', xml)
    response = parseString(data)
    print(response)
    itemNodes = response.getElementsByTagName('Item');
    results = []
    for item in itemNodes:
        itemId = getSingleValue(item, 'ItemID')
        itemTitle = getSingleValue(item, 'Title')
        itemPrice = getSingleValue(item, 'CurrentPrice')
        itemEnds = getSingleValue(item, 'EndTime')
        results.append((itemId, itemTitle, itemPrice, itemEnds))
    return results


def getCategory(query='', parentID=None, siteID='0'):
    lquery = query.lower()
    # build xml
    xml = "<?xml version='1.0' encoding='utf-8'?>" + \
          "<GetCategoriesRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">" + \
          "<RequesterCredentials><eBayAuthToken>" + \
          userToken + \
          "</eBayAuthToken></RequesterCredentials>" + \
          "<DetailLevel>ReturnAll</DetailLevel>" + \
          "<ViewAllNodes>true</ViewAllNodes>" + \
          "<CategorySiteID>" + siteID + "</CategorySiteID>"
    if parentID is None:
        xml += "<LevelLimit>1</LevelLimit>"
    else:
        xml += "<CategoryParent>" + str(parentID) + "</CategoryParent>"
    xml += "</GetCategoriesRequest>"
    data = sendRequest('GetCategories', xml)
    categoryList = parseString(data)
    catNodes = categoryList.getElementsByTagName('Category')
    for node in catNodes:
        catid = getSingleValue(node, 'CategoryID')
        name = getSingleValue(node, 'CategoryName')
        if name.lower().find(lquery) != -1:
            print(catid, name)


def getItem(itemID):
    xml = "<?xml version='1.0' encoding='utf-8'?>" + \
          "<GetItemRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">" + \
          "<RequesterCredentials><eBayAuthToken>" + \
          userToken + \
          "</eBayAuthToken></RequesterCredentials>" + \
          "<ItemID>" + str(itemID) + "</ItemID>" + \
          "<DetailLevel>ItemReturnAttributes</DetailLevel>" + \
          "</GetItemRequest>"
    data = sendRequest('GetItem', xml)
    result = {}
    response = parseString(data)
    result['title'] = getSingleValue(response, 'Title')
    sellingStatusNode = response.getElementsByTagName('SellingStatus')[0];
    result['price'] = getSingleValue(sellingStatusNode, 'CurrentPrice')
    result['bids'] = getSingleValue(sellingStatusNode, 'BidCount')
    seller = response.getElementsByTagName('Seller')
    result['feedback'] = getSingleValue(seller[0], 'FeedbackScore')

    attributeSet = response.getElementsByTagName('Attribute');
    attributes = {}
    for att in attributeSet:
        attID = att.attributes.getNamedItem('attributeID').nodeValue
        attValue = getSingleValue(att, 'ValueLiteral')
        attributes[attID] = attValue
    result['attributes'] = attributes
    return result


def makeLaptopDataset():
    searchResults = doSearch('laptop', categoryID=51148)
    result = []
    for r in searchResults:
        item = getItem(r[0])
        att = item['attributes']
        try:
            data = (float(att['12']), float(att['26444']),
                    float(att['26446']), float(att['25710']),
                    float(item['feedback'])
                    )
            entry = {'input': data, 'result': float(item['price'])}
            result.append(entry)
        except:
            print(item['title'] + ' failed')
    return result
